package dev.werillib.utils

import android.util.Base64
import java.security.KeyFactory
import java.security.KeyPairGenerator
import java.security.MessageDigest
import java.security.spec.X509EncodedKeySpec
import java.text.DecimalFormat
import java.util.*
import javax.crypto.Cipher

object StringUtil {

    fun isEmpty(str: String?): Boolean {
        return when (str) {
            null -> true
            "" -> true
            "null" -> true
            else -> false
        }
    }

    fun formatFloatZero(number: Double?): String {
        val decimalFormat = DecimalFormat("##########.##########")
        return decimalFormat.format(number)
    }

    fun matchIDNumber(id: String): Boolean {
        val regex = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$"
        return id.matches(regex.toRegex())
    }

    fun matchPhoneNumber(phone: String): Boolean {
        val regex =
            "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$"
        return phone.matches(regex.toRegex())
    }

    //字符串MD5加密
    fun MD5encode(str: String): String {
        val instance: MessageDigest = MessageDigest.getInstance("MD5")
        //对字符串加密，返回字节数组
        val digest: ByteArray = instance.digest(str.toByteArray())
        val sb = StringBuffer()
        for (b in digest) {
            //获取低八位有效值
            val i: Int = b.toInt() and 0xff
            //将整数转化为16进制
            var hexString = Integer.toHexString(i)
            if (hexString.length < 2) {
                //如果是一位的话，补0
                hexString = "0$hexString"
            }
            sb.append(hexString)
        }
        return sb.toString()
    }

    const val PUBLIC_KEY = "PUBLIC_KEY"
    const val PRIVATE_KEY = "PRIVATE_KEY"
    //生成rsa公钥和私钥字节数组
    fun genRsaByteKey(keySize: Int = 1024, algorithm: String = "RSA"): HashMap<String, ByteArray> {
        val instance = KeyPairGenerator.getInstance(algorithm)
        instance.initialize(keySize)
        val keyPair = instance.generateKeyPair()
        val publicKey = keyPair.public
        val privateKey = keyPair.private
        val keyMap = HashMap<String, ByteArray>()
        keyMap[PUBLIC_KEY] = publicKey.encoded
        keyMap["PRIVATE_KEY"] = privateKey.encoded
        return keyMap
    }

    //生成rsa公钥和私钥字字符串
    fun genRsaStringKey(keySize: Int = 1024, algorithm: String = "RSA"): HashMap<String, String> {
        val byteKey = genRsaByteKey(keySize, algorithm)
        val keyMap = HashMap<String, String>()
        keyMap[PUBLIC_KEY] = Base64.encodeToString(byteKey[PUBLIC_KEY], Base64.DEFAULT)
        keyMap[PRIVATE_KEY] = Base64.encodeToString(byteKey[PRIVATE_KEY], Base64.DEFAULT)
        return keyMap
    }

    val CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding"
    //rsa加密
    fun encrypt(publicKey: String, srcBytes: String, algorithm: String = CIPHER_ALGORITHM): String {
        //Cipher负责完成加密或解密工作，基于RSA
        val cipher = Cipher.getInstance(algorithm)
        val keyBytes = Base64.decode(publicKey, Base64.DEFAULT)
        val pkcs8KeySpec = X509EncodedKeySpec(keyBytes)
        val keyFactory = KeyFactory.getInstance("RSA")
        val publicK = keyFactory.generatePublic(pkcs8KeySpec)
        //根据公钥，对Cipher对象进行初始化
        cipher.init(Cipher.ENCRYPT_MODE, publicK)
        //加密，结果保存进resultBytes，并返回
        return Base64.encodeToString(cipher.doFinal(srcBytes.toByteArray()), Base64.DEFAULT)
    }

    //rsa解密
    fun decrypt(
        privateKey: String,
        encBytes: String,
        algorithm: String = CIPHER_ALGORITHM
    ): String {
        //Cipher负责完成加密或解密工作，基于RSA
        val cipher = Cipher.getInstance(algorithm)
        val keyBytes = Base64.decode(privateKey, Base64.DEFAULT)
        val pkcs8KeySpec = X509EncodedKeySpec(keyBytes)
        val keyFactory = KeyFactory.getInstance("RSA")
        val privateK = keyFactory.generatePrivate(pkcs8KeySpec)
        //根据公钥，对Cipher对象进行初始化
        cipher.init(Cipher.DECRYPT_MODE, privateK)
        //加密，结果保存进resultBytes，并返回
        return String(cipher.doFinal(Base64.decode(encBytes, Base64.DEFAULT)))

    }
}